/** \file TA_t.cc 
 * Test definitions for various TA functions.
 *
 * (C) Copyright by Semih Cemiloglu
 * All rights reserved, see COPYRIGHT file for details.
 *
 * $Id: MA_t.cc 110 2006-06-19 03:38:33Z semihc $
 *
 *
 */


#include "MASimple.hpp"
#include "MAExpon.hpp"
#include "MATri.hpp"
#include "MAVariable.hpp"
#include "MAWeighted.hpp"
#include <vector>
#include "TestHarness.hh"

using namespace std;
using namespace TC;


namespace {

  const unsigned DataSize = 56;

  const double ma_data[DataSize] = {
    25.0000, 24.8750, 24.7813, 24.5938, 24.5000, 24.6250, 25.2188,
    27.2500, 26.2500, 26.5938, 27.5938, 27.8750, 27.5313, 27.2188,
    26.9688, 26.7500, 27.4688, 27.3125, 27.5000, 27.5000, 26.7500,
    27.0625, 28.6563, 28.0938, 28.8125, 29.7813, 30.2813, 31.2813,
    31.5938, 31.8750, 32.5938, 33.5000, 33.7500, 33.2188, 32.9375,
    33.4375, 33.9063, 33.9688, 33.3125, 31.6875, 31.7500, 33.2500,
    32.9063, 31.6875, 31.4063, 27.9688, 29.5313, 30.5000, 31.5000,
    31.6875, 32.3750, 33.0938, 34.0938, 33.4688, 32.9688, 32.6875 };

  const double masimple_expect[DataSize] = {
    00.000, 00.000, 00.000, 00.000, 24.750, 24.675, 24.744, 25.238, 
    25.569, 25.988, 26.581, 27.113, 27.169, 27.363, 27.438, 27.269, 
    27.188, 27.144, 27.200, 27.306, 27.306, 27.225, 27.494, 27.613, 
    27.875, 28.481, 29.125, 29.650, 30.350, 30.963, 31.525, 32.169, 
    32.663, 32.988, 33.200, 33.369, 33.450, 33.494, 33.513, 33.263,
    32.925, 32.794, 32.581, 32.256, 32.200, 31.444, 30.700, 30.219,
    30.181, 30.238, 31.119, 31.831, 32.550, 32.944, 33.200, 33.263 };

  const double maexpon_expect[DataSize] = {
    25.000, 24.958, 24.899, 24.797, 24.698, 24.674, 24.856, 25.654,
    25.852, 26.100, 26.598, 27.023, 27.193, 27.201, 27.124, 26.999,
    27.156, 27.208, 27.305, 27.370, 27.163, 27.130, 27.639, 27.790,
    28.131, 28.681, 29.215, 29.903, 30.467, 30.936, 31.489, 32.159,
    32.689, 32.866, 32.890, 33.072, 33.350, 33.556, 33.475, 32.879,
    32.503, 32.752, 32.803, 32.431, 32.090, 30.716, 30.321, 30.381,
    30.754, 31.065, 31.502, 32.032, 32.720, 32.969, 32.969, 32.875 };

  const double matri_expect[DataSize] = {
    0, 0, 0, 0, 
    24.7535, 24.6493, 24.6597, 25.0174, 25.5729, 26.2118, 26.5834,
    26.9549, 27.2778, 27.5209, 27.4827, 27.2535, 27.0938, 27.0729,
    27.2222, 27.3472, 27.3715, 27.2639, 27.2813, 27.5104, 27.9827,
    28.4514, 29.0139, 29.6563, 30.3750, 31.0278, 31.5521, 32.0868,
    32.6528, 33.1424, 33.3577, 33.3299, 33.3090, 33.4653, 33.6424,
    33.4966, 32.9896, 32.4896, 32.3715, 32.4931, 32.4167, 31.6563,
    30.6632, 29.7743, 29.8264, 30.3577, 31.1979, 31.8229, 32.4757,
    33.0417, 33.4167, 33.3681 };

  const double mavariable_expect[DataSize] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    27.0625, 27.2449, 27.3156, 27.5214, 27.8532, 28.2828, 28.8728,
    29.4254, 30.0950, 30.7872, 31.5210, 32.2640, 32.5205, 32.6122,
    32.7938, 33.0229, 33.2101, 33.2213, 33.1336, 32.9517, 32.9604,
    32.9594, 32.8771, 32.7169, 31.6941, 31.3948, 31.3185, 31.3196,
    31.3203, 31.3521, 31.3629, 31.5854, 31.7125, 32.0013, 32.1223 };

  const double maweighted_expect[DataSize] = {
    0, 0, 0, 0,
    24.6646, 24.6229, 24.8042, 25.6396, 25.9771, 26.3188, 26.8542,
    27.2854, 27.4250, 27.4417, 27.3105, 27.0813, 27.1480, 27.1896,
    27.3083, 27.4083, 27.2229, 27.1417, 27.6188, 27.8188, 28.2188,
    28.8542, 29.4542, 30.1730, 30.8209, 31.3292, 31.8730, 32.5313,
    33.0583, 33.2438, 33.2271, 33.3063, 33.4854, 33.6584, 33.5979,
    32.9896, 32.4854, 32.5938, 32.6313, 32.3333, 32.0500, 30.6396,
    30.0021, 29.9354, 30.3625, 30.8646, 31.5771, 32.2354, 32.9896,
    33.2959, 33.3042, 33.1334 };


  vector<double> result;

}



TEST(MASimpleTest, Base)
{
     result.clear();

     // 5 period simple moving average
     MASimple(ma_data, ma_data+DataSize, 
              back_inserter(result), 
              5, ArrayAdaptor<double>());

     TC_TEST(result.size()==DataSize);
     for(unsigned i=0; i<DataSize; ++i)
       if(masimple_expect[i] > 0)
         TC_TESTFP(masimple_expect[i], result[i]);

     PrintElements(result, "MASimple");

}


TEST(MAExponTest, Base)
{
     result.clear();
     // 5 period exponential moving average
     MAExpon(ma_data, ma_data+DataSize,
             back_inserter(result), 
             5, ArrayAdaptor<double>());
     TC_TEST(result.size()==DataSize);
     PrintElements(result, "MAExpon-period");     

     result.clear();
     // 33.33% exponential moving average
     MAExponPct(ma_data, ma_data+DataSize,
                back_inserter(result), 
                0.3333, ArrayAdaptor<double>());
     TC_TEST(result.size()==DataSize);
     PrintElements(result, "MAExpon-percent");

     for(unsigned i=0; i<DataSize; ++i)
       if(maexpon_expect[i] > 0)
         TC_TESTFP(maexpon_expect[i], result[i]);

}


TEST(MATriTest, Base)
{
  result.clear();

     // 5 period triangular moving average
     MATri(ma_data, ma_data+DataSize, 
	   back_inserter(result), 
	   5, ArrayAdaptor<double>());

     TC_TEST(result.size()==DataSize);
     PrintElements(result, "MATri");

     for(unsigned i=0; i<DataSize; ++i)
       if(matri_expect[i] > 0)
         TC_TESTFP(matri_expect[i], result[i]);

}

TEST(MAVariableTest, Base)
{
     result.clear();

     // 5-period variable moving average
     MAVariable(ma_data, ma_data+DataSize, 
		back_inserter(result), 5,
		ArrayAdaptor<double>());

     TC_TEST(result.size()==DataSize);
     PrintElements(result, "MAVariable");

     for(unsigned i=0; i<DataSize; ++i)
       if(mavariable_expect[i] > 0)
         TC_TESTFP(mavariable_expect[i], result[i]);

}

TEST(MAWeightedTest, Base)
{
     result.clear();

     // 5-period weighted moving average
     MAWeighted(ma_data, ma_data+DataSize, 
		back_inserter(result), 5,
		ArrayAdaptor<double>());

     TC_TEST(result.size()==DataSize);
     PrintElements(result, "MAWeighted");

     for(unsigned i=0; i<DataSize; ++i)
       if(maweighted_expect[i] > 0)
         TC_TESTFP(maweighted_expect[i], result[i]);

}





